<script setup lang="ts">
import { reactive, ref } from "vue";

import { ElMessage, UploadProps, FormInstance, FormRules } from "element-plus";
import { Plus } from "@element-plus/icons-vue";

import { userUpdate } from "@/api/user/user";
import { UserUpdate } from "@/api/user";
import { uploadUri, upload, url } from "@/utils/storm/file";
import { FileOption } from "@/api/file";

import { useInfo } from "@/views/space/profile/info";
import { setUser } from "@/utils/auth";

defineOptions({
  name: "Space-Profile"
});

interface RuleForm {
  id: string;
  username: string;
  nickname?: string;
  avatar?: string;
}

const { userData } = useInfo();

const form = reactive<RuleForm>({
  id: userData.value.id,
  username: userData.value.username,
  nickname: userData.value.nickname,
  avatar: userData.value.avatar
});

const formRef = ref<FormInstance>();
const rules = reactive<FormRules>({
  id: [{ required: true, message: "id 不可为空", trigger: "blur" }],
  username: [{ required: true, message: "用户名不可为空", trigger: "blur" }],
  nickname: [{ required: true, message: "昵称不可为空", trigger: "blur" }],
  avatar: [{ required: true, message: "头像不可为空", trigger: "blur" }]
});

const imageUrl = ref(userData.value.avatarUrl ?? "");
const avatarUrl = ref(userData.value.avatarUrl ?? "");

const updateProfile = (formEl: FormInstance | undefined) => {
  if (!formEl) {
    return;
  }
  formEl.validate(valid => {
    if (valid) {
      const param: UserUpdate = {
        nickname: form.nickname ? form.nickname.trim() : undefined,
        avatar: form.avatar ? form.avatar.trim() : undefined
      };
      userUpdate({ param })
        .then(({ data }) => {
          form.id = data.id;
          form.username = data.username;
          form.nickname = data.nickname;
          form.avatar = data.avatar;
          avatarUrl.value = data.avatarUrl ?? "";

          setUser(data);
        })
        .catch(error => {
          console.error(error);
        });
    } else {
      ElMessage.error("参数校验失败");
      return false;
    }
  });
};

async function doUpload(uploadForm: { file: File }) {
  const file: File = uploadForm.file;
  const fileOption: FileOption = {
    mark: false,
    temp: 0
  };
  const { data } = await upload(file, fileOption);

  const id = data.id;
  const code = data.code;
  const fileParam = {
    id: id,
    code: code
  };

  const fileUrl = url(fileParam);
  imageUrl.value = fileUrl;

  form.avatar = id;
}

const handleAvatarSuccess: UploadProps["onSuccess"] = (
  response,
  uploadFile
) => {
  console.debug(response);
  imageUrl.value = URL.createObjectURL(uploadFile.raw!);
};

const beforeAvatarUpload: UploadProps["beforeUpload"] = rawFile => {
  if (rawFile.type !== "image/jpeg" && rawFile.type !== "image/png") {
    ElMessage.error("Avatar picture must be JPG format!");
    return false;
  } else if (rawFile.size / 1024 / 1024 > 1) {
    ElMessage.error("Avatar picture size can not exceed 1MB!");
    return false;
  }
  return true;
};
</script>

<template>
  <div>
    <el-row :gutter="24">
      <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
        <el-card>
          <el-upload
            class="avatar-uploader"
            :action="uploadUri"
            :show-file-list="false"
            :http-request="doUpload"
            :on-success="handleAvatarSuccess"
            :before-upload="beforeAvatarUpload"
          >
            <img v-if="imageUrl" :src="imageUrl" class="avatar" />
            <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
          </el-upload>

          <el-divider content-position="left">点击上传头像</el-divider>

          <el-form
            ref="formRef"
            label-width="80px"
            :model="form"
            :rules="rules"
            style="max-width: 480px"
          >
            <el-form-item label="ID" prop="id">
              <el-input disabled readonly v-model="form.id" />
            </el-form-item>
            <el-form-item label="用户名" prop="username">
              <el-input disabled readonly v-model="form.username" />
            </el-form-item>
            <el-form-item label="昵称" prop="nickname">
              <el-input clearable maxlength="32" v-model="form.nickname" />
            </el-form-item>
            <el-form-item label="头像" prop="avatar">
              <el-input readonly maxlength="32" v-model="form.avatar" />
            </el-form-item>
          </el-form>
          <el-button type="primary" plain @click="updateProfile(formRef)">
            修改
          </el-button>
        </el-card>
      </el-col>

      <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
        <el-card>
          <el-image
            v-if="avatarUrl"
            :src="avatarUrl"
            :preview-src-list="Array.of(avatarUrl)"
            fit="cover"
          />
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>

<style scoped>
.avatar-uploader .avatar {
  width: 178px;
  height: 178px;
  display: block;
}
</style>

<style>
.avatar-uploader .el-upload {
  border: 1px dashed var(--el-border-color);
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: var(--el-transition-duration-fast);
}

.avatar-uploader .el-upload:hover {
  border-color: var(--el-color-primary);
}

.el-icon.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  text-align: center;
}
</style>
